package com.serviportales.serviquality.maestroPlantillas.beans;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;
import javax.swing.tree.DefaultMutableTreeNode;

import org.apache.log4j.Logger;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;

import com.icesoft.faces.component.ext.RowSelectorEvent;
import com.icesoft.faces.component.selectinputtext.SelectInputText;
import com.liferay.util.bridges.jsf.common.FacesMessageUtil;
import com.rits.cloning.Cloner;
import com.serviportales.serviportales.beans.Contexto;
import com.serviportales.serviportales.frontController.ListHolder;
import com.serviportales.serviportales.model.DataTypesBeans;
import com.serviportales.serviportales.model.GenericNodeUserObject;
import com.serviportales.serviportales.model.GenericTreeModel;
import com.serviportales.serviportales.utils.BeansUtils;
import com.serviportales.serviportales.utils.SessionUtils;
import com.serviportales.serviquality.datatypes.DataTypesRef;
import com.serviportales.serviquality.datatypes.EstadoRegistro;
import com.serviportales.serviquality.exception.ServiqualityException;
import com.serviportales.serviquality.managers.MgrConstantes;
import com.serviportales.serviquality.managers.MgrNodos;
import com.serviportales.serviquality.managers.MgrPlantillaNodo;
import com.serviportales.serviquality.model.Nodo;
import com.serviportales.serviquality.model.Plantilla;
import com.serviportales.serviquality.model.PlantillaNodo;
import com.serviportales.serviquality.model.TipoNodo;

@ManagedBean(name = "fcConfigurarPlantilla", eager = true)
@ViewScoped
public class FCConfigurarPlantilla implements Serializable {

	private static final long serialVersionUID = 1L;

	private Logger logger = Logger.getLogger(getClass());

	private Plantilla plantilla;

	// Tree
	private PlantillaNodo plantillaNodoParent;
	private DefaultMutableTreeNode dmTreeNodeSelected;
	private GenericTreeModel<PlantillaNodo> plantillaTreeModel;

	// Maestro
	private boolean visiblePlantillaNodoForm;
	private PlantillaNodo plantillaNodoMaestro;
	private ListHolder<PlantillaNodo> nodos;
	private List<SelectItem> nodosAutocomplete;

	// Getters and setters
	public List<SelectItem> getNodosAutocomplete() {
		return nodosAutocomplete;
	}

	public void setNodosAutocomplete(List<SelectItem> nodosAutocomplete) {
		this.nodosAutocomplete = nodosAutocomplete;
	}

	public DefaultMutableTreeNode getDmTreeNodeSelected() {
		return dmTreeNodeSelected;
	}

	public void setDmTreeNodeSelected(DefaultMutableTreeNode dmTreeNodeSelected) {
		this.dmTreeNodeSelected = dmTreeNodeSelected;
	}

	public Plantilla getPlantilla() {
		return plantilla;
	}

	public void setPlantilla(Plantilla plantilla) {
		FacesContext context = FacesContext.getCurrentInstance();
		MessageSource messageSource = Contexto.getMessageSource();
		try {
			this.plantilla = plantilla;
			MgrPlantillaNodo mgrPlantillaNodo = ((MgrPlantillaNodo) Contexto.getApplicationContext().getBean("mgrPlantillaNodo"));
			plantillaTreeModel = mgrPlantillaNodo.createTree(plantilla);
			nodos.setFilter((PlantillaNodo) plantillaTreeModel.getRootNode());
		} catch (ServiqualityException serviqualityException) {
			FacesMessageUtil.error(context, messageSource.getMessage(serviqualityException.getMessage(), null, LocaleContextHolder.getLocale()));
			logger.error(serviqualityException.getMessage(), serviqualityException);
		}
	}

	public boolean isVisiblePlantillaNodoForm() {
		return visiblePlantillaNodoForm;
	}

	public void setVisiblePlantillaNodoForm(boolean visiblePlantillaNodoForm) {
		this.visiblePlantillaNodoForm = visiblePlantillaNodoForm;
	}

	public PlantillaNodo getPlantillaNodoMaestro() {
		return plantillaNodoMaestro;
	}

	public void setPlantillaNodoMaestro(PlantillaNodo plantillaNodoMaestro) {
		this.plantillaNodoMaestro = plantillaNodoMaestro;
	}

	public GenericTreeModel<PlantillaNodo> getPlantillaTreeModel() {
		return plantillaTreeModel;
	}

	public void setPlantillaTreeModel(GenericTreeModel<PlantillaNodo> plantillaTreeModel) {
		this.plantillaTreeModel = plantillaTreeModel;
	}

	public ListHolder<PlantillaNodo> getNodos() {
		return nodos;
	}

	public void setNodos(ListHolder<PlantillaNodo> nodos) {
		this.nodos = nodos;
	}

	// Generales
	public void initPlantillaNodo() {
		plantillaNodoMaestro.getPlantillaNodoPK().setPlantilla(plantilla);
		plantillaNodoMaestro.setParent(plantillaNodoParent);
		plantillaNodoMaestro.getPlantillaNodoPK().setNodo(new Nodo());
	}

	@PostConstruct
	public void init() {
		plantillaNodoParent = null;

		// Generales
		plantilla = new Plantilla();
		PlantillaNodo plantillaNodoFilter = new PlantillaNodo();
		plantillaNodoFilter.getPlantillaNodoPK().setPlantilla(plantilla);

		plantillaTreeModel = new GenericTreeModel<PlantillaNodo>();
		plantillaTreeModel.setRootNode("", plantillaNodoFilter);
		dmTreeNodeSelected = (DefaultMutableTreeNode) plantillaTreeModel.getRoot();

		// Maestro
		visiblePlantillaNodoForm = false;

		nodos = new ListHolder<PlantillaNodo>();
		nodos.setFilter(plantillaNodoFilter);

		nodosAutocomplete = new ArrayList<SelectItem>();
		plantillaNodoMaestro = new PlantillaNodo();
		initPlantillaNodo();

	}

	@SuppressWarnings("unchecked")
	public void nodeSelected(ActionEvent event) {
		Cloner cloner = new Cloner();
		FacesContext context = FacesContext.getCurrentInstance();
		String idNodo = SessionUtils.getRequesParameter(context, "idNodo");
		dmTreeNodeSelected = plantillaTreeModel.findNode(idNodo);
		PlantillaNodo plantillaNodoSelect = cloner.deepClone(((GenericNodeUserObject<PlantillaNodo>) dmTreeNodeSelected.getUserObject()).getValue());
		if (!dmTreeNodeSelected.equals(plantillaTreeModel.getRoot())) {
			plantillaNodoParent = plantillaNodoSelect;
		} else {
			plantillaNodoParent = null;
		}
		nodos.setFilter(plantillaNodoSelect);
		traerLista();
	}

	// Maestro
	public void closePopupPlantillaNodoForm() {
		visiblePlantillaNodoForm = false;
	}

	public void openPopupPlantillaNodoForm() {
		visiblePlantillaNodoForm = true;
		initPlantillaNodo();
	}

	public void refreshPlantilla() {
		FacesContext context = FacesContext.getCurrentInstance();
		MessageSource messageSource = Contexto.getMessageSource();
		try {
			MgrPlantillaNodo mgrPlantillaNodo = ((MgrPlantillaNodo) Contexto.getApplicationContext().getBean("mgrPlantillaNodo"));
			plantillaTreeModel = mgrPlantillaNodo.createTree(plantilla);
		} catch (ServiqualityException serviqualityException) {
			FacesMessageUtil.error(context, messageSource.getMessage(serviqualityException.getMessage(), null, LocaleContextHolder.getLocale()));
			logger.error(serviqualityException.getMessage(), serviqualityException);
		}
	}

	public void grabarPlantillaNodo() {
		FacesContext context = FacesContext.getCurrentInstance();
		MessageSource messageSource = Contexto.getMessageSource();
		try {
			MgrPlantillaNodo mgrPlantillaNodo = ((MgrPlantillaNodo) Contexto.getApplicationContext().getBean("mgrPlantillaNodo"));
			mgrPlantillaNodo.grabarPlantillaNodo(plantillaNodoMaestro);
			closePopupPlantillaNodoForm();

			traerLista();

			FacesMessageUtil.info(context, messageSource.getMessage(ServiqualityException.GRABAR_EXITO, null, LocaleContextHolder.getLocale()));
		} catch (ServiqualityException serviqualityException) {
			FacesMessageUtil.error(context, messageSource.getMessage(serviqualityException.getMessage(), null, LocaleContextHolder.getLocale()));
			logger.error(serviqualityException.getMessage(), serviqualityException);
		}
	}

	public void traerLista() {
		FacesContext context = FacesContext.getCurrentInstance();
		try {
			MgrPlantillaNodo mgrPlantillaNodo = ((MgrPlantillaNodo) Contexto.getApplicationContext().getBean("mgrPlantillaNodo"));
			nodos.setSource(mgrPlantillaNodo.buscarChildren(nodos.getFilter()));
		} catch (ServiqualityException serviqualityException) {
			MessageSource messageSource = Contexto.getMessageSource();
			FacesMessageUtil.error(context, messageSource.getMessage(serviqualityException.getMessage(), null, LocaleContextHolder.getLocale()));
			logger.error(serviqualityException.getMessage(), serviqualityException);
		}
	}

	public void selectedPlantillaNodo(RowSelectorEvent rowSelectorEvent) {
		Cloner cloner = new Cloner();
		try {
			for (PlantillaNodo plantillaNodoLista : nodos.getSource()) {
				if (plantillaNodoLista.isSelected()) {
					plantillaNodoMaestro = cloner.deepClone(plantillaNodoLista);
					visiblePlantillaNodoForm = true;
					break;
				}
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
	}

	public void eliminarPlantillaNodo() {
		FacesContext context = FacesContext.getCurrentInstance();
		MessageSource messageSource = Contexto.getMessageSource();
		try {
			if (plantillaNodoMaestro.isSelected()) {
				((MgrPlantillaNodo) Contexto.getApplicationContext().getBean("mgrPlantillaNodo")).eliminarPlantillaNodo(plantillaNodoMaestro);
				initPlantillaNodo();
				FacesMessageUtil.info(context, messageSource.getMessage(ServiqualityException.ELIMINAR_EXITO, null, LocaleContextHolder.getLocale()));
				traerLista();
			}
			closePopupPlantillaNodoForm();
		} catch (ServiqualityException serviqualityException) {
			FacesMessageUtil.error(context, messageSource.getMessage(serviqualityException.getMessage(), null, LocaleContextHolder.getLocale()));
			logger.error(serviqualityException.getMessage(), serviqualityException);
		}
	}

	public void selectNodoValueChanged(ValueChangeEvent event) {
		FacesContext context = FacesContext.getCurrentInstance();
		MgrNodos mgrNodos = ((MgrNodos) Contexto.getApplicationContext().getBean("mgrNodos"));
		MessageSource messageSource = (MessageSource) Contexto.getMessageSource();
		try {
			if (event.getComponent() instanceof SelectInputText) {
				SelectInputText autoComplete = (SelectInputText) event.getComponent();

				String nombre = (String) event.getNewValue();
				Nodo nodo = new Nodo();
				nodo.setNombre(nombre);
				nodo.setEstadoRegistro((EstadoRegistro) DataTypesBeans.getInstance().getBeanById(EstadoRegistro.class, DataTypesRef.ESTADO_REGISTRO_ACTIVO));
				nodo.getNodoPK().setTipoNodo(new TipoNodo());
				nodo.getNodoPK().getTipoNodo().setNivel(BeansUtils.getDatoAtributo(nodos, "filter.plantillaNodoPK.nodo.nodoPK.tipoNodo.nivel", -1) + 1);

				List<Nodo> listNodos = mgrNodos.buscarNodosByNivel(nodo, Integer.parseInt(messageSource.getMessage(MgrConstantes.KEY_SIZE_AUTOCOMPLETE, null, LocaleContextHolder.getLocale())));
				nodosAutocomplete = new ArrayList<SelectItem>();
				for (Nodo nodoList : listNodos) {
					nodosAutocomplete.add(new SelectItem(nodoList, nodoList.getNombre()));
				}
				if (autoComplete.getSelectedItem() != null) {
					plantillaNodoMaestro.getPlantillaNodoPK().setNodo((Nodo) autoComplete.getSelectedItem().getValue());
				} else {
					plantillaNodoMaestro.getPlantillaNodoPK().setNodo(new Nodo());
				}
			}
		} catch (ServiqualityException serviqualityException) {
			FacesMessageUtil.error(context, messageSource.getMessage(serviqualityException.getMessage(), null, LocaleContextHolder.getLocale()));
			logger.error(serviqualityException.getMessage(), serviqualityException);
		} catch (Exception exception) {
			FacesMessageUtil.error(context, messageSource.getMessage(exception.getMessage(), null, LocaleContextHolder.getLocale()));
			logger.error(exception.getMessage(), exception);
		}
	}
}
